#! /usr/bin/env python
# -*- coding: utf-8 -*-

import socket
import re
import os
import time
import random
import traceback
import json

import FileHostProtoType

class ultitem(FileHostProtoType.HostItem):
    def __init__(self, name, type, id, link, encrypt_name='', server_name=''): 
        #id save as D111111 or F1111111  
        FileHostProtoType.HostItem.__init__(self, name, type, id, link, encrypt_name, server_name)

class uploadedto(FileHostProtoType.FileHostProcess):
    def __init__(self,user,pwd):
        FileHostProtoType.FileHostProcess.__init__(self)
        self.hostname = "uploaded.net"
        self._opener = None
        self._cj = None
        self._user = user
        self._pwd = pwd
        self.islogin = False
        self.page = 0
        self._cookieCurl = self._user + '_uploadedto.cookie'
        self._cookieCurl = os.path.join(os.path.dirname(__file__), self._cookieCurl)
        self.vowel=('a','e','i','o','u')
        self.nonvowel=('b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z')
    
    def get_admincode(self):
        admincode = ''
        i = 3
        while i>0:
            admincode += self.nonvowel[random.randint(0,len(self.nonvowel)-1)]
            admincode += self.vowel[random.randint(0,len(self.vowel)-1)]
            i -= 1
        return admincode

    def login(self):
        '''
        login to FileSonic
        return opener object which includes cookies
        '''
        self.generateOpener()
        if self.check_cookie():
            return True
        self.fherr.write('login to uploaded.net %s/%s...' % (self._user,'*'*len(self._pwd)))
        loginData = {'id' : self._user, \
                'pw' : self._pwd }
        response = self.loginFileHost("http://uploaded.net/io/login", loginData)
        # user info can be found in cookie
        index = self.post_request("http://uploaded.net")
        if self._user.lower() not in index.lower():
            self.fherr.write("post:"+response)
            self.fherr.write("index:"+index)
            self.fherr.write("User %s Failed to Login uploaded.net." % self._user)
            return False
        self.fherr.write("User %s logined." % self._user)
        self.islogin = True
        return True
    
    def check_cookie(self):
        self.fherr.write('Checking Cookie...')
        response = self.post_request("http://uploaded.net")
        if response and self._user in response:
            self.fherr.write("User %s Status : Logined." % self._user)
            self.islogin = True             
            return True
        self.fherr.write("[%s]User %s Status : not Logined." % (time.ctime(), self._user))
        #self.fherr.write(response)
        return False  
      
    def getFileList(self):
        #TODO
        filelist = []
        page = 0
        while True:
            pagefile = self.getFileFromPage(page=page)
            filelist.extend(pagefile)
            if not pagefile:
                break
            page += 1
        return filelist
    
    def getFileFromPage(self, page=0, limit=5000):
        self.fherr.write("Get file from page %d" % page)
        filelist = []
        data = {"dir":"desc",
                "limit":limit,
                "order":"date",
                "page":page,
                "search":"" }           
        response = self.post_request("http://uploaded.net/io/me/list/files", data)
        content = json.loads(response)
        entry_list = content.get("list", [])
        if entry_list:
            for entry in entry_list:
                item = ultitem(entry["filename"], 'file', entry["id"], "http://ul.to/%s"% entry["id"])
                filelist.append(item)
        return filelist
    
    def getFilesFromLastPage(self, page=0, limit=100):
        return self.getFileFromPage(page, limit)
        
    def getFilesFromFolder(self, folder):
        #TODO
        filelist = []
        id  = folder.id
        return filelist
    
    def getFolderList(self):   
        foundFolders = []
        #TODO
        foundFolders.sort()
        return foundFolders 
    
    def find(self, filenames=[], filelist=None):
        '''
        open the filelist page according to opener with cookies
        '''
        found = []
        if filelist is None:
            filelist = self.getFileList()        
        filelistlower = [fl.name.lower() for fl in filelist]
        todel = []
        for fl in filenames:
            try:
                index = filelistlower.index(os.path.basename(fl).lower())
                found.append(filelist[index])
                todel.append(fl)
            except:
                continue
        for d in todel:
            filenames.remove(d)
        found.sort()
        return found

    def findFolder(self, foldername):        
        folders = self.getFolderList()
        for f in folders:
            if foldername == f.name:
                return f
        return None

    def createFolder(self, newfolder):
        foundfolder = self.findFolder(newfolder)
        if foundfolder is None:
            #wupload no longer allow user to create subdir 
            return self.__newFolder(newfolder)
        self.fherr.write("Folder %s exsits." % newfolder)
        return foundfolder

    def __newFolder(self, newfolder, parentfolder=None):
        #TODO
        return
    
    def moveto(self, items, destFolder):
        #TODO
        return
    
    def upload_web(self, file, progressLog=None, other_args=None):
        return self.upload_web_local(file, progressLog, other_args)
    
    def upload_web_local(self, file, progressLog=None, other_args=None):
        content=self.post_request("http://uploaded.net/js/script.js").encode("utf8")        
        serverlink = self.get_upload_key(content, "uploadServer = ", -2, "'")
        
        if self.other_params.get('mirror'):
            server_no = int(self.other_params.get('mirror'))
            serverlink = "http://stor1%03d.uploaded.net/" % (server_no)
            self.fherr.write("use custom server mirror: %s" % serverlink)
            
        indexpage = self.post_request("http://uploaded.net/").encode("utf8")
        user_id = self.get_upload_key(indexpage, 'id="user_id"', -2)
        user_pw = self.get_upload_key(indexpage, 'id="user_pw"', -2)
        admincode = self.get_admincode()
        
        if not serverlink:
            self.fherr.write("Failed to get upload link for %s" % file)
            return
        upload_link = "{0}upload?admincode={1}&id={2}&pw={3}".format(serverlink, admincode, user_id, user_pw)
        print upload_link
        data = {"Filename":self.rename_func(file).encode("utf8"),
                "Upload":"Submit Query",
                "Filedata":open(file, 'rb')}
        self.fherr.write("Uploading...%s" % file)
        
        callback = None
        if progressLog is not None:
            callback = progressLog.write
        result = self.post_file(upload_link, data, self.get_cookies(), callback=callback)
        #result
        #print result
        tokens = result.split(',')
        if len(tokens) != 2:
            self.fherr.write("upload response:" +result)
            self.fherr.write("orz:" + upload_link)
            self.fherr.write("Failed to upload %s" % file)
            #time.sleep(300)
            return
        code = tokens[0]
        link = "http://ul.to/" + code + '/' + self.rename_func(file)
        item = ultitem(os.path.basename(file), 'file', code, link, self.rename_func(file))
        self.newupload.append(item)
        self.fhout.write(item.format()) 
        return item
    
    def upload_to_ftp(self, file, progressLog=None, other_args=None):
        host = 'ftp://ftp.ul.to'
            
        userpwd = ('%s:%s' % (self._user, self._pwd)).encode('utf8')
        target_name = self.rename_func(file)
        callback = None
        if progressLog is not None:
            callback = progressLog.write

        retry = 10
        while retry > 0:
            self.fherr.write("Uploading...%s to %s" % (file, host))
            try:
                self.upload_file_to_ftp(host, userpwd, file, \
                                target=target_name.encode('utf8'), \
                                callback=callback)
            except:
                self.fherr.write(traceback.format_exc())
                time.sleep(60)
                retry -= 1
                continue
            break
        if retry == 0:
            self.fherr.write('max retry. failed')
            return
        
        
        #find new upload file:
        time.sleep(30)
        times = self.wait_time/60 + 1
        while times > 0:            
            rootfiles = self.getFilesFromLastPage()
            find_result = self.find([target_name,], rootfiles)
            if find_result:
                new_file = find_result[0]     
                item = ultitem(os.path.basename(file), \
                              'file', \
                              new_file.id, \
                              new_file.link + '/' +new_file.server_name, \
                              target_name,\
                              new_file.server_name)
                self.newupload.append(item)
                return item
            times -= 1
            time.sleep(60)


if __name__ == "__main__":
    pass